// @Author EthanScriptOn
// @Desc
package op_example

import (
	"context"
	"fmt"
	"gitee.com/fatzeng/srf_switch_basic_components/common/identity"
	"gitee.com/fatzeng/srf_switch_basic_components/util"
	"gitee.com/fatzeng/srf_switch_stream_bridge/framework/actuator"
	"gitee.com/fatzeng/srf_switch_stream_bridge/framework/operator"
	"time"
)

type DelayedCallDetectionMultiChannelDataOperator struct {
	*identity.IdentityInformationCarrier
}

func (d *DelayedCallDetectionMultiChannelDataOperator) Execute(ctx *actuator.SrfSwitchBridgeActuatorContext, configIdentifier interface{}, structureParam interface{}) (resp interface{}, err error) {
	var operatorConfig *operator.DelayedMultiChannelDataOperatorConfig
	if operatorConfig, err = d.GetOperatorConfig(configIdentifier); err != nil {
		return nil, err
	}
	ctxWithCancel, cancel := context.WithCancel(context.Background())
	defer cancel()
	signal := make(chan struct{})
	time.AfterFunc(operatorConfig.Delayed, func() {
		defer util.HandleErr(&err)
		resp, err = d.DoExecute(ctx, operatorConfig, structureParam)
		close(signal)
	})
	select {
	case <-ctxWithCancel.Done():
		return nil, ctxWithCancel.Err()
	case <-signal:
		return resp, err
	}
}

func (d *DelayedCallDetectionMultiChannelDataOperator) GetOperatorConfig(configIdentifier interface{}) (*operator.DelayedMultiChannelDataOperatorConfig, error) {
	if configIdentifier == nil {
		return nil, fmt.Errorf("config identifier is nil")
	}
	config := operator.GetOperatorConfig(configIdentifier)
	if config == nil {
		return nil, fmt.Errorf(fmt.Sprintf("can not found extend_operator config with: %+v", configIdentifier))
	}
	configResp, ok := config.(*operator.DelayedMultiChannelDataOperatorConfig)
	if !ok {
		return nil, fmt.Errorf(fmt.Sprintf("extend_operator config type mismatch: %+v", configIdentifier))
	}
	return configResp, nil
}

func (d *DelayedCallDetectionMultiChannelDataOperator) DoExecute(ctx *actuator.SrfSwitchBridgeActuatorContext, config *operator.DelayedMultiChannelDataOperatorConfig, params interface{}) (interface{}, error) {
	operatorIdentifier := config.GetOperatorIdentifier(true)
	if operatorIdentifier == nil {
		return nil, fmt.Errorf("can not found operatorIdentifier")
	}
	operatorInstance := operator.GetOperator(operatorIdentifier)
	if operatorInstance == nil {
		return nil, fmt.Errorf(fmt.Sprintf("can not found extend_operator with: %+v", operatorIdentifier))
	}
	return operatorInstance.Execute(ctx, config.GetOperatorConfigIdentifier(true), params)
}
